package cn.bossfriday.im.common.service;

import cn.bossfriday.common.plugin.PluginResource;
import cn.bossfriday.im.common.db.AppInfoDao;
import cn.bossfriday.im.common.db.entity.AppInfo;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static cn.bossfriday.im.common.constant.ImConstant.CACHE_DEFAULT_INITIAL_CAPACITY;
import static cn.bossfriday.im.common.constant.ImConstant.CACHE_EXPIRE_TWO_HOURS;

/**
 * AppInfoService
 *
 * @author chenx
 */
@Slf4j
@Service
public class AppInfoService {

    @PluginResource
    private AppInfoDao appInfoDao;

    /**
     * Key: appId
     */
    private Cache<Long, Optional<AppInfo>> appInfoCache = Caffeine.newBuilder()
            .initialCapacity(CACHE_DEFAULT_INITIAL_CAPACITY)
            .maximumSize(CACHE_DEFAULT_INITIAL_CAPACITY)
            .expireAfterWrite(CACHE_EXPIRE_TWO_HOURS, TimeUnit.SECONDS)
            .build();

    /**
     * getAppInfo
     *
     * @param appId
     * @return
     */
    public AppInfo getAppInfo(Long appId) {
        Optional<AppInfo> cached = this.appInfoCache.getIfPresent(appId);
        if (Objects.nonNull(cached)) {
            return cached.orElse(null);
        }

        return this.appInfoCache.get(appId, key -> Optional.ofNullable(this.appInfoDao.getById(key))).orElse(null);
    }
}
